﻿// 示例代码 2-2
// 异常的捕获和应用
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <thread> // sleep_for的声明，可跨平台
using namespace std;

class Exception
{
public:
	Exception(int id, const string& errmsg)
		: _id(id)
		, _errmsg(errmsg)
	{}

	virtual string what() const
	{
		return _errmsg;
	}

	const int& getid() const
	{
		return _id;
	}

protected:
	int _id;
	string _errmsg;
};

class SqlException : public Exception
{
public:
	SqlException(int id, const string& errmsg, const string& sql)
		: Exception(id, errmsg)
		, _sql(sql)
	{}

	virtual string what() const
	{
		string str = "SqlException ";
		str += _errmsg;
		str += "->";
		str += _sql;

		return str;
	}

private:
	const string _sql;
};

class CacheException : public Exception
{
public:
	CacheException(int id, const string& errmsg)
		: Exception(id, errmsg)
	{}

	virtual string what() const
	{
		string str = "CacheException ";
		str += _errmsg;

		return str;
	}
};

class HttpException : public Exception
{
public:
	HttpException(int id, const string& errmsg, const string& type)
		: Exception(id, errmsg)
		, _type(type)
	{}

	virtual string what() const
	{
		string str = "HttpException ";
		str += _type;
		str += ":";
		str += _errmsg;

		return str;
	}

private:
	const string _type;
};

void SQLMgr()
{
	if (0 == rand() % 7)
	{
		throw SqlException(100, "权限不足", "select * from name = '张三'");
	}
	else
	{
		cout << "SQLMgr 调用成功" << endl;
	}
}

void CacheMgr()
{
	if (0 == rand() % 5)
	{
		throw CacheException(100, "权限不足");
	}
	else if (0 == rand() % 6)
	{
		throw CacheException(101, "数据不存在");
	}
	else
	{
		cout << "CacheMgr 调用成功" << endl;
	}

	SQLMgr();
}

void HttpServer()
{
	if (0 == rand() % 3)
	{
		throw HttpException(100, "请求资源不存在", "get");
	}
	else if (0 == rand() % 4)
	{
		throw HttpException(101, "权限不足", "post");
	}
	else
	{
		cout << "HttpServer 调用成功" << endl;
	}

	CacheMgr();
}

void Test2()
{
	srand(static_cast<unsigned>(time(0)));

	for (int i = 12; i; --i)
	{
		this_thread::sleep_for(chrono::seconds(1));// 通过chrono库指定当前线程休眠的单位是秒seconds，Windows/Linux通用

		try
		{
			HttpServer();
		}
		catch (const Exception& e) // 捕获基类，使得基类对象和派⽣类对象都可以被捕获
		{
			cout << "【" << e.what() << "】" << endl;
		}
			catch (...)
		{
			cout << "【" << "Unknown Exception" << "】" << endl;
		}
	}
}

#define VAL1 1

void Test3()
{
//#define VAL1 1
	std::cout << VAL1 << std::endl;
}

int main()
{
	//Test2();
	Test3();
	std::cout << VAL1 << std::endl;

	return 0;
}